/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.piza.toolcenter.operation;

import com.piza.toolcenter.beans.TableConfig;
import com.piza.toolcenter.dao.DBInfoMapper;
import com.piza.toolcenter.dao.GeneratorConfigMapper;
import com.piza.toolcenter.model.DBInfo;
import com.piza.toolcenter.model.DBInfoExample;
import com.piza.toolcenter.model.GeneratorConfig;
import com.piza.toolcenter.model.GeneratorConfigExample;
import java.io.File;
import java.io.FileWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;

/**
 *
 * @author cwb
 */
public class OperationTree {

    public static final OperationTree operationTree=new OperationTree();

    private static SqlSession sqlSession=null;

    private static SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd_HH_mm_ss");

    private static Logger logger= Logger.getLogger(OperationTree.class);
    private OperationTree(){
        
    }
    
    public static String convertTableName(String tableName){
        String domainName="";
        
        char[] cc=tableName.toCharArray();
        boolean toUpper=true;
        for(int i=0;i<cc.length;i++){
            if(cc[i]=='_'){
              toUpper=true;  
              continue;
            }
            if(toUpper){
               cc[i]=Character.toUpperCase(cc[i]);
               toUpper=false;
            }else{
                cc[i]=Character.toLowerCase(cc[i]);
            }
            domainName+=cc[i];
        }
        
        
        return domainName;
    }

    public static String getSchema(String connURL){
        
        return connURL.substring(connURL.
                lastIndexOf("/")+1) ;
    }
    public static String testJDBC(DBInfo dbInfo){
        String result="Ok";

        try{
            Class.forName(dbInfo.getDriverClass());
            Connection conn = DriverManager.getConnection(dbInfo.getConnectUrl(), dbInfo.getUserName(), dbInfo.getPassword());
        }catch(Exception e){
            logger.error(e.getMessage());
            result="Unknown exception";
        }

        return result;
    }


    public static boolean saveGenConfig(GeneratorConfig config){
        boolean ok=false;
        try{
        GeneratorConfigMapper configMapper=new OperationTree().getMapperClass(GeneratorConfigMapper.class);
        if(config.getId()==null){
            configMapper.insert(config);
        }else{
            configMapper.updateByPrimaryKey(config);
        }
        commitSession();
        ok=true;
        }catch (Exception e){
            e.printStackTrace();
            ok=false;
        }
        return ok;
    }

    public static boolean saveJDBCConfig(DBInfo dbInfo){
        boolean ok=false;
		
		try{

		DBInfoMapper dbInfoMapper=operationTree.getMapperClass(DBInfoMapper.class);
                if(dbInfo.getId()==null){
                 dbInfoMapper.insert(dbInfo);
                }else{
                    dbInfoMapper.updateByPrimaryKey(dbInfo);
                }
                 commitSession();
		ok=true;
		}catch(Exception e){
                    e.printStackTrace();
                ok=false;
		}
        return ok;
    }

    public static List<DBInfo> getAllDBInfo() throws Exception{
        DBInfoExample example=new DBInfoExample();
        example.or().andIdGreaterThan(0);
        return operationTree.getMapperClass(DBInfoMapper.class).selectByExample(example);
    }

    public static List<GeneratorConfig> getAllConfigInfo() throws Exception{
        GeneratorConfigExample example=new GeneratorConfigExample();
        example.or().andIdGreaterThan(0);
        return operationTree.getMapperClass(GeneratorConfigMapper.class).selectByExample(example);
    }

    private static void commitSession(){
        if(sqlSession!=null){
            sqlSession.commit();
        }
    }
    public <T> T getMapperClass(Class<T> mapperClass) throws Exception{
        T obj=null;
        SqlSessionFactory sqlSessionFactory=operationTree.getSqlSessionFactory();
         sqlSession = sqlSessionFactory.openSession();
        obj= sqlSession.getMapper(mapperClass);
        if(obj==null){
            sqlSession.getConfiguration().addMapper(mapperClass);
            obj=sqlSession.getMapper(mapperClass);
        }
        return obj;
        
    }

    public SqlSessionFactory getSqlSessionFactory(){
		try{
		String resource = "com/piza/toolcenter/xml/mybatis_config.xml";
		Reader reader = Resources.getResourceAsReader(resource);
		SqlSessionFactory sqlSession = new SqlSessionFactoryBuilder().build(reader);
		return sqlSession;
		}catch(Exception e){
			e.printStackTrace();
			logger.error("error when build cone sqlsession ");
			return null;
		}
   }

    public static List<String> getDBTables(DBInfo dbInfo){
        
        DBManager dbm=new DBManager(dbInfo);
        
        return dbm.getDBTables();
        
    }

    
    
    public static String generateConfig(SessionContext context){
        String configXML="";
        DBInfo dbInfo=(DBInfo)context.getItem("CurrentDBInfo");
        Map<String,TableConfig> selectedTables=(Map<String,TableConfig>)context.getItem("SelectedTables");
        GeneratorConfig genConfig=(GeneratorConfig)context.getItem("genConfig");
         try {
	  Properties p=new Properties();
		   //System.out.println(getSysPath());
	  p.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "template");
          p.setProperty("resource.loader", "class");
          p.setProperty("class.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
//        p.setProperty("jar.resource.loader.cache", "false");
//        p.setProperty("jar.resource.loader.modificationCheckInterval", "2");
           VelocityEngine ve = new VelocityEngine();
           ve.init(p);
           String path="template/GeneratorConfig.vm";
           Template t = ve.getTemplate(path);

           VelocityContext velocityContext = new VelocityContext();
           velocityContext.put("dbInfo",dbInfo);
           velocityContext.put("tables", selectedTables);
           velocityContext.put("genConfig", genConfig);

           StringWriter writer = new StringWriter();
           t.merge(velocityContext, writer);
           //String genPath=Application.getInstance(ToolCenterApp.class).getContext().getResourceMap(ToolCenterView.class).getString("APP_DATA_PATH");
           String genPath=System.getProperty("APP_DATA_PATH");
           logger.debug("APP_DATA_PATH="+genPath);
            genPath+="/config_"+genDateStr()+".xml";
           File configFile=new File(genPath);
           if(!configFile.exists()){
               configFile.createNewFile();
           }
           FileWriter fwriter=new FileWriter(configFile);
           t.merge(velocityContext, fwriter);
           fwriter.flush();
           context.addItem("configxml", configFile);
           configXML=writer.toString();
          // System.out.println(configXML);

       } catch (Exception ex) {

        ex.printStackTrace();
       }

        
        return configXML;
    }


    public static String genDateStr(){

        return format.format(new Date());
    }

    public static String getSysPath(){
		String path=OperationTree.class.getClassLoader().getSystemResource("").getPath();
		String os =System.getProperty("os.name");
		if(os!=null && os.startsWith("Windows")){
			return path.substring(1, path.length());
		}
		return path;
	}
    
    
    public static String mybatisGenerate(SessionContext context){
        try{
        MybatisGenerator mg=new MybatisGenerator();
        String[] arg=new String[3];
        arg[0]="-configfile";
        File configFile=(File)context.getItem("configxml");
        arg[1]=configFile.getAbsolutePath();
        arg[2]="-overwrite";
        mg.run(arg);
        }catch(Exception e){
            logger.error(e.getMessage());
            e.printStackTrace();
            return "encountered error";
        }
        return "generated successful!";
    }
}
